package com.ruoyi.system.service.impl;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.DataStatistics;
import com.ruoyi.system.domain.vo.Datastatisticsvo;
import com.ruoyi.system.domain.vo.DeptVo;
import com.ruoyi.system.domain.vo.EpmInformationHistoryVo;
import com.ruoyi.system.mapper.EmpcountMapper;
import com.ruoyi.system.service.IEmpcountService;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

//import static org.apache.velocity.util.StringUtils.capitalizeFirstLetter;


@Service
public class EmpcountServiceImpl implements IEmpcountService {

    @Autowired
    private EmpcountMapper empcountMapper;


    @Override
    public List<Datastatisticsvo> Empcount() {
        List<Datastatisticsvo> dataStatisticsVoList = empcountMapper.findUserCounts();
        dataStatisticsVoList.forEach(dataStatisticsVo -> {
            long totalCount = accumulateCount(dataStatisticsVo, dataStatisticsVoList,"totalCount")+dataStatisticsVo.getTotalCount();
            dataStatisticsVo.setTotalCount(totalCount);
        });
        return dataStatisticsVoList ;
    }

    @Override
    public void resetList(List<Datastatisticsvo> list, String date) {
        empcountMapper.insertHistorycount(list,date);
    }



    @Override
    public List<Datastatisticsvo> Empcount2(String date) {
        List<Datastatisticsvo> dataStatisticsVoList = empcountMapper.findUserCounts2(date);
        return (dataStatisticsVoList);
    }

    @Override
    public List<EpmInformationHistoryVo> EmpOps(Integer range){
//        将empcountMapper.EmpOps(year, month, day)查询到的数据赋值给epmInformationHistoryVos

        List<EpmInformationHistoryVo> epmInformationHistoryVos = empcountMapper.EmpOps(range);
        return epmInformationHistoryVos;
    }
    @Override
    public DataStatistics EmpcountByTime(Integer minTime, Integer maxTime, Long deptId) {
        List<DeptVo> deptVoList = empcountMapper.findUserCountsByTime(minTime, maxTime,deptId);
        DataStatistics dataStatistics = new DataStatistics();
        for (DeptVo deptVo : deptVoList){
            deptVo.setTotalNum(DeptVo.getToltalNum(deptVoList));
        }
        dataStatistics.setDeptId(deptId);
        dataStatistics.setDeptempNum(DeptVo.getToltalNum(deptVoList));
//        在列表中根据deptId查询部门名称赋值给dataStatistics
        dataStatistics.setDeptName(deptVoList.stream().filter(deptVo -> deptVo.getDeptId().equals(deptId)).map(DeptVo::getDeptName).findFirst().orElse(""));
        return dataStatistics;
    }



    @Override
    public List<Datastatisticsvo> getGenderList() {
        List<Datastatisticsvo> dataStatisticsVoList = empcountMapper.countByGender();

//处理原始部门树，计算部门人数
        dataStatisticsVoList.forEach(dataStatisticsVo -> {
            long accumulatedTotalCount = accumulateCount(dataStatisticsVo, dataStatisticsVoList,"accumulatedTotalCount")+dataStatisticsVo.getAccumulatedTotalCount();
            long accumulatedFemaleCount = accumulateCount(dataStatisticsVo, dataStatisticsVoList,"accumulatedFemaleCount")+dataStatisticsVo.getAccumulatedFemaleCount();
            dataStatisticsVo.setAccumulatedFemaleCount(accumulatedFemaleCount);
            long accumulatedMaleCount = accumulateCount(dataStatisticsVo, dataStatisticsVoList,"accumulatedMaleCount")+dataStatisticsVo.getAccumulatedMaleCount();
            dataStatisticsVo.setAccumulatedMaleCount(accumulatedMaleCount);
            dataStatisticsVo.setAccumulatedTotalCount(accumulatedTotalCount);
        });
        dataStatisticsVoList.forEach(dataStatisticsVo -> {
            // 除0处理，保留两位小数
            double maleRatio = 0;
            double femaleRatio = 0;
            if (dataStatisticsVo.getAccumulatedTotalCount() != 0) {
                maleRatio = (dataStatisticsVo.getAccumulatedMaleCount() * 1.0 / dataStatisticsVo.getAccumulatedTotalCount());
                femaleRatio = (dataStatisticsVo.getAccumulatedFemaleCount() * 1.0 / dataStatisticsVo.getAccumulatedTotalCount());
            }

// 保留两位小数
            DecimalFormat df = new DecimalFormat("#.00");
            dataStatisticsVo.setMaleRatio(Double.parseDouble(df.format(maleRatio)));
            dataStatisticsVo.setFemaleRatio(Double.parseDouble(df.format(femaleRatio)));

        });
//        List<Datastatisticsvo> deptTree = buildTree(dataStatisticsVoList);
        return dataStatisticsVoList ;
    }

    @Override
    public List<Datastatisticsvo> getRegionList() {
        List<Datastatisticsvo> dataStatisticsVoList = empcountMapper.countByRegion();
        dataStatisticsVoList.forEach(dataStatisticsVo -> {
            long region0 = accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region0")+dataStatisticsVo.getRegion0();
            dataStatisticsVo.setRegion0(region0);
            dataStatisticsVo.setRegion1(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region1")+dataStatisticsVo.getRegion1());
            dataStatisticsVo.setRegion2(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region2")+dataStatisticsVo.getRegion2());
            dataStatisticsVo.setRegion3(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region3")+dataStatisticsVo.getRegion3());
            dataStatisticsVo.setRegion4(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region4")+dataStatisticsVo.getRegion4());
            dataStatisticsVo.setRegion5(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region5")+dataStatisticsVo.getRegion5());
            dataStatisticsVo.setRegion6(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region6")+dataStatisticsVo.getRegion6());
            dataStatisticsVo.setRegion7(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region7")+dataStatisticsVo.getRegion7());
            dataStatisticsVo.setRegion8(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region8")+dataStatisticsVo.getRegion8());
            dataStatisticsVo.setRegion9(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region9")+dataStatisticsVo.getRegion9());
            dataStatisticsVo.setRegion10(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region10")+dataStatisticsVo.getRegion10());
            dataStatisticsVo.setRegion11(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region11")+dataStatisticsVo.getRegion11());
            dataStatisticsVo.setRegion12(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region12")+dataStatisticsVo.getRegion12());
            dataStatisticsVo.setRegion13(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region13")+dataStatisticsVo.getRegion13());
            dataStatisticsVo.setRegion14(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region14")+dataStatisticsVo.getRegion14());
            dataStatisticsVo.setRegion15(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region15")+dataStatisticsVo.getRegion15());
            dataStatisticsVo.setRegion16(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region16")+dataStatisticsVo.getRegion16());
            dataStatisticsVo.setRegion17(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region17")+dataStatisticsVo.getRegion17());
            dataStatisticsVo.setRegion18(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region18")+dataStatisticsVo.getRegion18());
            dataStatisticsVo.setRegion19(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region19")+dataStatisticsVo.getRegion19());
            dataStatisticsVo.setRegion20(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region20")+dataStatisticsVo.getRegion20());
            dataStatisticsVo.setRegion21(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region21")+dataStatisticsVo.getRegion21());
            dataStatisticsVo.setRegion22(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region22")+dataStatisticsVo.getRegion22());
            dataStatisticsVo.setRegion23(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region23")+dataStatisticsVo.getRegion23());
            dataStatisticsVo.setRegion24(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region24")+dataStatisticsVo.getRegion24());
            dataStatisticsVo.setRegion25(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region25")+dataStatisticsVo.getRegion25());
            dataStatisticsVo.setRegion26(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region26")+dataStatisticsVo.getRegion26());
            dataStatisticsVo.setRegion27(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region27")+dataStatisticsVo.getRegion27());
            dataStatisticsVo.setRegion28(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region28")+dataStatisticsVo.getRegion28());
            dataStatisticsVo.setRegion29(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region29")+dataStatisticsVo.getRegion29());
            dataStatisticsVo.setRegion30(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region30")+dataStatisticsVo.getRegion30());
            dataStatisticsVo.setRegion31(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region31")+dataStatisticsVo.getRegion31());
            dataStatisticsVo.setRegion32(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region32")+dataStatisticsVo.getRegion32());
            dataStatisticsVo.setRegion33(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region33")+dataStatisticsVo.getRegion33());
            dataStatisticsVo.setRegion34(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region34")+dataStatisticsVo.getRegion34());
//            dataStatisticsVo.setRegion35(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"region35")+dataStatisticsVo.getRegion35());

        });
        return dataStatisticsVoList ;
    }

    @Override
    public List<Datastatisticsvo> getEducationalLeveList() {
        List<Datastatisticsvo> dataStatisticsVoList = empcountMapper.countByEducation();
        dataStatisticsVoList.forEach(dataStatisticsVo -> {
            long highEducationalLevel0 = accumulateCount(dataStatisticsVo, dataStatisticsVoList,"highEducationalLevel0")+dataStatisticsVo.getHighEducationalLevel0();
            dataStatisticsVo.setHighEducationalLevel0(highEducationalLevel0);
            dataStatisticsVo.setHighEducationalLevel1(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"highEducationalLevel1")+dataStatisticsVo.getHighEducationalLevel1());
            dataStatisticsVo.setHighEducationalLevel2(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"highEducationalLevel2")+dataStatisticsVo.getHighEducationalLevel2());
            dataStatisticsVo.setHighEducationalLevel3(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"highEducationalLevel3")+dataStatisticsVo.getHighEducationalLevel3());
            dataStatisticsVo.setHighEducationalLevel4(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"highEducationalLevel4")+dataStatisticsVo.getHighEducationalLevel4());
            dataStatisticsVo.setHighEducationalLevel5(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"highEducationalLevel5")+dataStatisticsVo.getHighEducationalLevel5());
            dataStatisticsVo.setHighEducationalLevel6(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"highEducationalLevel6")+dataStatisticsVo.getHighEducationalLevel6());

        });
        return dataStatisticsVoList ;
    }

    @Override
    public List<Datastatisticsvo> getGangweiList(){
        List<Datastatisticsvo> dataStatisticsVoList = empcountMapper.getGangweiList();
        dataStatisticsVoList.forEach(dataStatisticsVo -> {
            dataStatisticsVo.setPostId1(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"postId1")+dataStatisticsVo.getPostId1());
            dataStatisticsVo.setPostId2(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"postId2")+dataStatisticsVo.getPostId2());
            dataStatisticsVo.setPostId3(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"postId3")+dataStatisticsVo.getPostId3());
            dataStatisticsVo.setPostId4(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"postId4")+dataStatisticsVo.getPostId4());
            dataStatisticsVo.setPostId5(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"postId5")+dataStatisticsVo.getPostId5());
            dataStatisticsVo.setPostId6(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"postId6")+dataStatisticsVo.getPostId6());
            dataStatisticsVo.setPostId7(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"postId7")+dataStatisticsVo.getPostId7());
            dataStatisticsVo.setPostId8(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"postId8")+dataStatisticsVo.getPostId8());
            dataStatisticsVo.setPostId9(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"postId9")+dataStatisticsVo.getPostId9());

        });
        return dataStatisticsVoList ;
    }

    @Override
    public List<Datastatisticsvo> getAgeList() {
        List<Datastatisticsvo> dataStatisticsVoList = empcountMapper.countByAge();
        dataStatisticsVoList.forEach(dataStatisticsVo -> {
            dataStatisticsVo.setAge1(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"age1")+dataStatisticsVo.getAge1());
            dataStatisticsVo.setAge2(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"age2")+dataStatisticsVo.getAge2());
            dataStatisticsVo.setAge3(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"age3")+dataStatisticsVo.getAge3());
            dataStatisticsVo.setAge4(accumulateCount(dataStatisticsVo, dataStatisticsVoList,"age4")+dataStatisticsVo.getAge4());
        });
        return dataStatisticsVoList ;
    }
    /*
    小组件
    * */
    private List<Datastatisticsvo> buildTree(List<Datastatisticsvo> dataStatisticsVoList) {
        List<Datastatisticsvo> returnList = new ArrayList<>();
        List<Long> dpetList = dataStatisticsVoList.stream().map(Datastatisticsvo::getDeptId).collect(Collectors.toList());
        for (Datastatisticsvo dataStatisticsVo : dataStatisticsVoList) {
            if (!dpetList.contains(dataStatisticsVo.getParentId())) {
                recursionFn(dataStatisticsVoList, dataStatisticsVo);
                returnList.add(dataStatisticsVo);
            }
            if (returnList.isEmpty()) {
                returnList = dataStatisticsVoList;
            }
        }
        return returnList;
    }
    private void recursionFn(List<Datastatisticsvo> list, Datastatisticsvo t)
    {
        // 得到子节点列表
        List<Datastatisticsvo> childList = getChildList(list, t);
        t.setChildren(childList);
        for (Datastatisticsvo tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }
    private List<Datastatisticsvo> getChildList(List<Datastatisticsvo> list, Datastatisticsvo t)
    {
        List<Datastatisticsvo> tlist = new ArrayList<Datastatisticsvo>();
        Iterator<Datastatisticsvo> it = list.iterator();
        while (it.hasNext())
        {
            Datastatisticsvo n = (Datastatisticsvo) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    private boolean hasChild(List<Datastatisticsvo> list, Datastatisticsvo t)
    {
        return getChildList(list, t).size() > 0;
    }
/*    private long accumulateCountsRecursively(Datastatisticsvo currentVo, List<Datastatisticsvo> dataStatisticsVoList) {
        if (currentVo == null || currentVo.getDeptId() == null||dataStatisticsVoList == null || dataStatisticsVoList.isEmpty()) {
            return 0L;
        }
        return dataStatisticsVoList.stream()
                .filter(dataStatisticsVo1 -> dataStatisticsVo1.getParentId().equals(currentVo.getDeptId()))
                .mapToLong(vo -> vo.getAccumulatedTotalCount() + accumulateCountsRecursively(vo, dataStatisticsVoList))
                .sum();
    }*/
/*private long accumulateCountsRecursively(Datastatisticsvo currentVo, List<Datastatisticsvo> dataStatisticsVoList) {
    if (currentVo == null || currentVo.getDeptId() == null || dataStatisticsVoList == null || dataStatisticsVoList.isEmpty()) {
        return 0L;
    }

    // 确保至少有一个匹配项
    List<Datastatisticsvo> filteredList = dataStatisticsVoList.stream()
            .filter(dataStatisticsVo1 -> dataStatisticsVo1.getParentId().equals(currentVo.getDeptId()))
            .collect(Collectors.toList());

    if (filteredList.isEmpty()) {
        return 0L; // 如果没有匹配项则返回0
    }

    return filteredList.stream()
            .mapToLong(vo -> {
                // 防止vo.getAccumulatedTotalCount()为null的情况（虽然这种情况很少见）
                Long accumulatedTotalCount = vo.getAccumulatedTotalCount();
                if (accumulatedTotalCount == null) {
                    accumulatedTotalCount = 0L;
                }
                return accumulatedTotalCount + accumulateCountsRecursively(vo, dataStatisticsVoList);
            })
            .sum();
}*/

//    实体类中的参数名和使用方法用T占位符
    private long accumulateCount(Datastatisticsvo currentVo, List<Datastatisticsvo> dataStatisticsVoList, String T) {
    if (currentVo == null || currentVo.getDeptId() == null || dataStatisticsVoList == null || dataStatisticsVoList.isEmpty()) {
        return 0L;
    }

    String methodName = "get" + capitalizeFirstLetter(T);
    MethodHandle methodHandle = getGetMethod(currentVo.getClass(), methodName);

    if (methodHandle == null) {
        throw new IllegalArgumentException("Method " + methodName + " not found in " + currentVo.getClass().getName());
    }

    return dataStatisticsVoList.stream()
            .filter(dataStatisticsVo1 -> dataStatisticsVo1.getParentId().equals(currentVo.getDeptId()))
            .mapToLong(vo -> {
                try {
                    Long value = (Long) methodHandle.invokeExact(vo);
                    return value + accumulateCount(vo, dataStatisticsVoList, T);
                } catch (Throwable e) {
                    throw new RuntimeException("Error invoking method " + methodName, e);
                }
            })
            .sum();
}

    private MethodHandle getGetMethod(Class<?> clazz, String methodName) {
        try {
            MethodHandles.Lookup lookup = MethodHandles.lookup();
            MethodType methodType = MethodType.methodType(Long.class);
            MethodHandle methodHandle = lookup.findVirtual(clazz, methodName, methodType);
            return methodHandle;
        } catch (NoSuchMethodException | IllegalAccessException e) {
            return null;
        }
    }
    public static String capitalizeFirstLetter(String data) {
        String firstLetter = data.substring(0, 1).toUpperCase();
        String restLetters = data.substring(1);
        return firstLetter + restLetters;
    }
 /* @Test
    public void testBuildTree() {
        // 准备测试数据
        List<Datastatisticsvo> dataStatisticsVoList = new ArrayList<>();
        Datastatisticsvo root = new Datastatisticsvo(1L, 0L,  "Root", 0L, 1L, 1L, 0.0, 0.0, new ArrayList<>());

        Datastatisticsvo child1 = new Datastatisticsvo(2L, 1L, "Child1",  1L, 0L, 1L, 0.0, 0.0, new ArrayList<>());

        Datastatisticsvo child2 = new Datastatisticsvo(3L, 1L, "Child2",  2L, 0L, 2L, 0.0, 0.0, new ArrayList<>());
        Datastatisticsvo child3 = new Datastatisticsvo(4L, 2L,"Grandchild1",   1L, 2L, 3L, 0.0, 0.0, new ArrayList<>());
        dataStatisticsVoList.add(root);
        dataStatisticsVoList.add(child1);
        dataStatisticsVoList.add(child2);
        dataStatisticsVoList.add(child3);


        //处理原始部门树，计算部门人数
        dataStatisticsVoList.forEach(dataStatisticsVo -> {
            long accumulatedTotalCount = accumulateCount(dataStatisticsVo, dataStatisticsVoList,"accumulatedTotalCount")+dataStatisticsVo.getAccumulatedTotalCount();
            long accumulatedFemaleCount = accumulateFemaleCountsRecursively(dataStatisticsVo, dataStatisticsVoList)+dataStatisticsVo.getAccumulatedFemaleCount();
            dataStatisticsVo.setAccumulatedFemaleCount(accumulatedFemaleCount);
            long accumulatedMaleCount = accumulateMaleCountsRecursively(dataStatisticsVo, dataStatisticsVoList)+dataStatisticsVo.getAccumulatedMaleCount();
            dataStatisticsVo.setAccumulatedMaleCount(accumulatedMaleCount);
            dataStatisticsVo.setAccumulatedTotalCount(accumulatedTotalCount);
        });
        dataStatisticsVoList.forEach(dataStatisticsVo -> {
            // 除0处理，保留两位小数
            dataStatisticsVo.setMaleRatio(dataStatisticsVo.getAccumulatedMaleCount()*1.0/dataStatisticsVo.getAccumulatedTotalCount());
            dataStatisticsVo.setFemaleRatio(dataStatisticsVo.getAccumulatedFemaleCount()*1.0/dataStatisticsVo.getAccumulatedTotalCount());
        });

        System.out.println(dataStatisticsVoList);
    }*/



}

